package com.bsf.wcp;

import com.alibaba.fastjson.JSON;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.ref.SoftReference;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;

import org.apache.commons.lang.StringUtils;

/**
 * @author: chejiangyi
 * @create: 2019-05-10 08:58
 **/
@Component
@Slf4j
@Getter
public class Wcp {
    @Value("${wcp.url}")
    private String wcpUrl;
    @Value("${wcp.home.releaturl}")
    private String wcpHomeReleatUrl;
    @Value("${wcp.detail.urltag}")
    private String wcpDetailUrlTag;
    @Value("${dingding.callbackurls}")
    private String dingdingCallBackUrls;
    @Value("${dingding.mdtemplate}")
    private String dingdingMdTemplate;
    @Value("${spider.sleep}")
    private Integer spiderSleep;
    @Value("${spider.skiptitle}")
    private  String spiderSkipTitle;

    private long lastRunTime = System.currentTimeMillis();

    public void run()
    {
        try {
            val homeUrl = wcpUrl+wcpHomeReleatUrl;
            val doc = Jsoup.connect(homeUrl)
                    .header("Accept", "*/*")
                    .header("Accept-Encoding", "gzip, deflate")
                    .header("Accept-Language","zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
                    //.header("Content-Type", "application/json;charset=UTF-8")
                    .ignoreContentType(true);
            val docment = doc.get().body();
            val links = docment.select("a[href]");
            if (links.size() > 0) {
                ArrayList<ParseResult> parseResultList= new ArrayList<>();
                links.forEach(item -> {
                    val result = spiderDetail(item);
                    if(result!=null)
                        parseResultList.add(result);
                });
                sendDingDing(parseResultList);
            }

        }
        catch (Exception e)
        {
            log.error("访问wcp出错:"+e.getMessage());
        }
    }

    private ParseResult spiderDetail(Element item)
    {
        var detailUrl="";
        try
        {
            var href = item.attr("href");
            if(href.contains("javascript:"))
                return null;
            detailUrl = new URL(new URL(wcpUrl) ,href).toString();
            if(detailUrl.contains(wcpDetailUrlTag))
            {
                ParseResult r = new ParseResult();
                val doc1 = Jsoup.connect(detailUrl)
                        .header("Accept", "*/*")
                        .header("Accept-Encoding", "gzip, deflate")
                        .header("Accept-Language","zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
                        .ignoreContentType(true);
                val docment1 = doc1.get();
                val trs = docment1.select("#DocVersionsBoxId table tr");
                r.sourcetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(trs.get(1).child(0).text());
                if(r.sourcetime.getTime()<=lastRunTime)
                {    return null;}
                r.time = DateFormatUtils.format(r.sourcetime, "yyyy-MM-dd HH:mm:ss");
                r.title = docment1.select(".doc_title").text(); //docment1.select("title").text();
                if(r.title.toString().contains(spiderSkipTitle))
                {   return null;}
                r.url = detailUrl;
                r.author = trs.get(1).child(1).text();
                r.remark =  trs.get(1).child(2).text();
                r.category = docment1.select(".doc-conentinfo a[title]").text();
                if (trs.size() > 2) {
                    r.edittype = "更新";
                } else {
                    r.edittype = "新增";
                    r.remark="新增文章";
                }
                return r;

            }
        }
        catch (Exception exp)
        {
            log.error("解析wcp详情url错误,"+"error:"+exp.getMessage() +"detailurl:"+detailUrl);
        }
        return null;
    }

    private void sendDingDing(ArrayList<ParseResult> parseResultList)
    {
        Arrays.stream(StringUtils.strip(dingdingCallBackUrls, ",").split(",")).forEach(url->{
            if(StringUtils.isNotEmpty(url)) {
                parseResultList.forEach(c -> {
                    try {
                        if(c.sourcetime.getTime()>lastRunTime)
                            lastRunTime=c.sourcetime.getTime();

                        var text1 = new String[]{dingdingMdTemplate};
                        Arrays.stream(c.getClass().getDeclaredFields()).forEach(o -> {
                            o.setAccessible(true);
                            try {
                                text1[0] = text1[0].replace("{$" + o.getName() + "}", o.get(c).toString());
                            }catch (Exception e)
                            {}
                        });

                        var data = new HashMap<String,Object>();
                        data.put("msgtype","markdown");
                        data.put("markdown", new HashMap<String,Object>(){
                            {
                                put("title","WCP知识库-更新");
                                put("text",text1[0]);
                            }
                        });

                        Jsoup.connect(url)
                                .header("Content-Type", "application/json;charset=UTF-8")
                                .ignoreContentType(true)
                                .postDataCharset("utf-8")
                                .requestBody(JSON.toJSONString(data))
                                .post();
                    }
                    catch (Exception exp)
                    {
                        log.error("钉钉通知失败,error:"+exp.getMessage());
                    }
                });
            }
        });
    }


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private static class ParseResult
    {
        private Object title="";
        private Object author="";
        private Object time="";
        private Object url="";
        private Object category="";
        private Object edittype="";//更新，新增
        private Object remark="";//备注

        private Date sourcetime= null;
    }
}
